package com.study.common.utils;

import com.study.web.entity.Person;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 标签处理器工具类
 * @author yaojinshan
 * @since 2020年12月11日09:46:09
 * @version 1.0
 */
@SuppressWarnings("all")
public class FreeMarkerUtil {
    public static void main(String[] args) {
//        testBaseDataTypeReplace();
//        testStaticWordReplace();
        testDynamicWordReplace();
    }
    /**
     * 测试基础数据类型替换
     */
    private static void testBaseDataTypeReplace(){
        Map<Object, Object> valueMap = new HashMap<>();
        valueMap.put("byteKey",-128);
        valueMap.put("shortKey",(short)2);
        valueMap.put("intKey",666);
        valueMap.put("floatKey",0.1f);
        valueMap.put("doubleKey",0.03d);
        valueMap.put("charKey",'A');
        valueMap.put("longKey",1l);
        valueMap.put("booleanKey",true);

        int[] intArray = new int[]{1,2,3};
        valueMap.put("intArray",intArray);

        List<Person> personList = new ArrayList<>();
        personList.add(new Person("1","张三"));
        personList.add(new Person("2","李四"));
        valueMap.put("personList",personList);

        Map<String,List<Person>> map1 = new HashMap<>();
        map1.put("map",personList);

        valueMap.put("m1",map1);

        testPrint(valueMap);
    }

    /**
     * 测试输出
     * @param valueMap
     */
    private static void testPrint(Map valueMap){
        OutputStreamWriter writer = null;
        try {
            String ftlPath = "src/main/resources/template";
            Configuration configuration = new Configuration();
            //设置 template 的目录所在地址，非必要配置
            configuration.setDirectoryForTemplateLoading(new File(ftlPath));
            //设置 对象包装类为默认类型
            configuration.setObjectWrapper(new DefaultObjectWrapper());
            //根据文件名称 获取模板
            Template template = configuration.getTemplate("test.ftl");
            //在控制台输出内容
            writer = new OutputStreamWriter(System.out);
            //变量值替换
            template.process(valueMap,writer);
            writer.flush();
            writer.close();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 测试word文件静态替换
     *  实验证明：
     *      0.首先要在动态填值的文本域中，先用唯一标识占位，后续方便查找和替换成表达式
     *      1.不能直接使用word作为模板文本，必须将word文件另存为 xml或者ftl 格式才可以
     *      2.使用freemarker 表达式时，在${}不能出现无关内容
     * @return
     */
    private static void testStaticWordReplace(){
        Map valueMap = new HashMap();
        valueMap.put("name","张三");
        valueMap.put("age",18);
        valueMap.put("sex","男");
        OutputStreamWriter writer = null;
        try {
            String ftlPath = "src/main/resources/template";
            Configuration configuration = new Configuration();
            //设置 template 的目录所在地址，非必要配置
            configuration.setDirectoryForTemplateLoading(new File(ftlPath));
            //设置 对象包装类为默认类型
            configuration.setObjectWrapper(new DefaultObjectWrapper());
            //根据文件名称 获取模板
            Template template = configuration.getTemplate("staticWordReplace.xml");
            File targetFile = new File("D:/staticWordReplace.docx");
            //这个地方不能使用FileWriter因为需要指定编码类型否则生成的word文档会因为有无法识别的编码而无法打开
            writer = new OutputStreamWriter(new FileOutputStream(targetFile),"utf-8");
            //变量值替换
            template.process(valueMap,writer);
            writer.flush();
            writer.close();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 测试word文件动态替换
     *  实验证明：
     *      0.首先要在动态填值的文本域中，先用唯一标识占位，后续方便查找和替换成表达式
     *      1.不能直接使用word作为模板文本，必须将word文件另存为 xml或者ftl 格式才可以
     *      2.使用freemarker 表达式时，在${}不能出现无关内容
     *      3.动态文件不能直接打开，因为格式是乱的，填值之后才可以可以打开的文件
     *      4. 在文件 dynamicWordReplace.ftl 中 会有对循环标签体的 解释
     *      5. xx_has_next 代表 是否有下一个节点
     *      6. xx_index 代表 当前循环位置
     * @return
     */
    private static void testDynamicWordReplace(){

        Map valueMap = new HashMap();
        List<Person> personList = new ArrayList<>();
        personList.add(new Person("zhangsan","张三"));
        personList.add(new Person("lisi","李四"));
        personList.add(new Person("wangwu","王五"));
        valueMap.put("personList",personList);
        OutputStreamWriter writer = null;
        try {
            String ftlPath = "src/main/resources/template";
            Configuration configuration = new Configuration();
            //设置 template 的目录所在地址，非必要配置
            configuration.setDirectoryForTemplateLoading(new File(ftlPath));
            //设置 对象包装类为默认类型
            configuration.setObjectWrapper(new DefaultObjectWrapper());
            //根据文件名称 获取模板
            Template template = configuration.getTemplate("dynamicWordReplace2.ftl");
//            Template template = configuration.getTemplate("dynamicWordReplace.ftl");
//            Template template = configuration.getTemplate("dynamicWordReplace.xml");
            File targetFile = new File("D:/dynamicWordReplace.docx");
            //这个地方不能使用FileWriter因为需要指定编码类型否则生成的word文档会因为有无法识别的编码而无法打开
            writer = new OutputStreamWriter(new FileOutputStream(targetFile),"utf-8");
            //变量值替换
            template.process(valueMap,writer);
            writer.flush();
            writer.close();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 完整模板
     * @param rootMap
     * @param fileTemplatePath
     */
    public static void completeTemplate(Map<Object,Object> rootMap,String fileTemplatePath){

    }
}
